home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / other / rcvfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  6.3 KB  |  247 lines

  1. #
  2. /***************************************************************************\
  3. *                                         *
  4. *     R C V F I L E . C                                *
  5. *                                         *
  6. *     Written by Dave Crocker.                            *
  7. *     Rewritten by J. Onions, combined the original two programs into        *
  8. *     one to make documentation easier, not to mention updates etc.        *
  9. *     most of the original text kept.                        *
  10. *     Reworked again by Doug Kingston to make secure and clean.            *
  11. *                                         *
  12. *     usage:   rcvfile directory [-l logfile] [-m]                *
  13. *    "directory" specifies where the files will be created under        *
  14. *    "-l logfile" specifies the logging file for the program            *
  15. *       "-m" instructs the program to make directories if necessary        *
  16. *                                        *
  17. *     Message has a Subject: line of the form                    *
  18. *     Subject: rcvfile filename                            *
  19. *                                         *
  20. *     The body of the message will always be filed under the "directory"    *
  21. *     specified (".." is trapped).  This can be made "/" to enable        *
  22. *     fileing anywhere.                                *
  23. *                                         *
  24. \***************************************************************************/
  25.  
  26. #include "util.h"
  27. #include "mmdf.h"
  28. #include <pwd.h>
  29. #include <sys/stat.h>
  30.  
  31. extern int errno;
  32. extern int sentprotect;
  33. extern char *locname;
  34.  
  35. extern char *compress();
  36. extern char *rindex();
  37.  
  38. long    filesize;
  39. int    makedirs = 0;
  40. char    *filedir = (char *)0;
  41. char    *logfile = (char *)0;
  42. char    dirname[LINESIZE];
  43. char    filename[LINESIZE];
  44. char    subjbuf[LINESIZE];
  45. char    frombuf[LINESIZE];
  46. char    datebuf[LINESIZE];
  47. char    buffer[BUFSIZ];
  48. char    inbuf[BUFSIZ];
  49.  
  50. /* */
  51. main (argc, argv)
  52. int    argc;
  53. char    **argv;
  54. {
  55.     register int nread;
  56.     register int fd;
  57.     register int i;
  58.     FILE *output;
  59.  
  60.     mmdf_init (argv[0]);
  61.     setbuf (stdin, inbuf);
  62.  
  63.     for (i = 1; i < argc; i++) {
  64.         if (argv[i][0] != '-') {
  65.         if (filedir != (char *)0) {
  66.         fputs ("  *** directory already specified\n", stderr);
  67.         finish (RP_PARM);
  68.         }
  69.         filedir = argv[i];
  70.     } else {
  71.         if (strcmp (argv[i], "-l") == 0) {
  72.             if (i+1 == argc) {
  73.             fputs ("  *** missing logfile after -l\n", stderr);
  74.             finish (RP_PARM);
  75.         }
  76.             logfile = argv[++i];
  77.         } else if (strcmp(argv[i], "-m") == 0) {
  78.         makedirs++;
  79.         } else {
  80.         fprintf (stderr, "  *** unknown parameter '%s'\n", argv[i]);
  81.         finish (RP_PARM);
  82.         }
  83.     }
  84.     }
  85.  
  86.     init_log();
  87.  
  88.     if (filedir == (char *)0) {
  89.     fputs ("  *** missing filing directory\n", stderr);
  90.     finish (RP_PARM);
  91.     }
  92.     sprintf(filename, "%s/", filedir);
  93.  
  94.     /*
  95.      *  parse the header, find interesting info and save it.
  96.      */
  97.     while (fgets (buffer, sizeof buffer, stdin) != NULL && buffer[0] != '\n') {
  98.     if (equal ("to", buffer, 2) || equal ("cc", buffer, 2))
  99.         fputs (buffer, stderr);
  100.                   /* log "to" and "cc" information */
  101.     if (equal ("date", buffer, 4))
  102.         compress (&buffer[strindex (":", buffer) + 1], datebuf);
  103.                   /* save date    text in buffer        */
  104.     if (equal ("from", buffer, 4))
  105.         compress (&buffer[strindex (":", buffer) + 1], frombuf);
  106.                   /* save from    text in buffer        */
  107.     if (equal ("subject", buffer, 7))
  108.         compress (&buffer[strindex (":", buffer) + 1], subjbuf);
  109.                   /* save subject text in buffer        */
  110.     }
  111.  
  112.     /* We accept "rcvarch" for backwords compat, and its the same size */
  113.     if (!equal ("rcvfile", subjbuf, 7) && !equal ("rcvarch", subjbuf, 7))
  114.     {                             /* doesn't have the command word      */
  115.     fputs ("  *** Subject lacks keyword\n", stderr);
  116.     finish (RP_PARM);
  117.     }
  118.  
  119.     compress (&subjbuf[7], subjbuf);
  120.     if ((strlen(subjbuf)+strlen(filename)+1) > sizeof filename) {
  121.     fputs ("  *** filename too long\n", stderr);
  122.     finish (RP_PARM);
  123.     }
  124.  
  125.     /*
  126.      *  Must not contain ".." and must not be null, we also make
  127.      *  some other sanity/security checks.
  128.      */
  129.     if (subjbuf[0] == '\0'
  130.       || strcmp(subjbuf, ".") == 0
  131.       || strcmp(subjbuf, "..") == 0
  132.       || initstr("../", subjbuf, 3)
  133.       || strindex(subjbuf, "/../") != (-1)
  134.       || endstr("/..", subjbuf, 3)) {
  135.     fputs ("  *** Illegal filename\n", stderr);
  136.     finish (RP_PARM);
  137.     }
  138.  
  139.     strcat (filename, subjbuf);
  140.     dirpart (filename);
  141.  
  142.     if ((fd = creat (filename, sentprotect)) < OK) {
  143.     if( !makedirs ) {
  144.         fperror("  *** creat");
  145.         finish (RP_FCRT);
  146.     } else {
  147.         if (creatdir (dirname, 0755, 0, 0) < 0) {
  148.         fprintf( stderr, "%s *** unsuccessful mkdir\n",
  149.              dirname);
  150.         finish (RP_FCRT);
  151.         }
  152.     }
  153.     if ((fd = creat (filename, sentprotect)) < 0) {
  154.         fperror("  *** creat after mkdir");
  155.         finish (RP_FCRT);
  156.     }
  157.     }
  158.     if (chmod (filename, sentprotect) < 0) {
  159.     fperror("  *** chmod");
  160.     finish (RP_FIO);
  161.     }
  162.  
  163.     if ((output = fdopen (fd, "a")) == NULL) {
  164.     fperror("  *** fdopen");
  165.     finish (RP_FIO);
  166.     }
  167.     filesize = 0;
  168.     while ((nread = fread (buffer, sizeof(char), sizeof buffer, stdin)) != 0) {
  169.     if (fwrite (buffer, sizeof(char), nread, output) != nread) {
  170.         fperror("  *** File output error");
  171.         finish (RP_FIO);
  172.     }
  173.         filesize += nread;
  174.     }
  175.     if (ferror(stdin)) {
  176.     fperror("  *** file input error");
  177.     fclose (output);
  178.     unlink (filename);
  179.     finish (RP_FIO);
  180.     }
  181.     fclose (output);
  182.     fprintf (stderr, "  (%ldc)\n", filesize);
  183.     notify (datebuf, frombuf, filename, filesize);
  184.     finish (RP_MOK);
  185.  
  186.     /* NOTREACHED */
  187. }
  188. /* */
  189.  
  190. finish (retval)
  191.     int retval;
  192. {
  193.     fprintf (stderr, "%s\n\n", rp_valstr (retval));
  194.     fflush (stderr);
  195.  
  196.     exit (retval == RP_MOK ? 0 : RP_MECH);
  197. }
  198.  
  199. notify (thedate, thefrom, file, size)
  200. char    *thedate, *thefrom, *file;
  201. long    size;
  202. {
  203.     extern struct passwd *getpwuid ();
  204.     struct stat statbuf;
  205.     struct passwd *owner;
  206.     char linebuf[2*LINESIZE];
  207.  
  208.     if (stat(dirname, &statbuf) < 0 ||
  209.     (owner = getpwuid(statbuf.st_uid)) == NULL) {
  210.     fprintf (stderr, "  *** get owner error (%d)\n", errno);
  211.     }
  212.  
  213.     sprintf (linebuf, "[%s]%s got %ld characters.\n\nFrom %s, sent %s.\n",
  214.          locname, file, size, thefrom, thedate);
  215.  
  216.     if (ml_1adr (NO, NO, "FILE SERVER", (char *) 0, owner -> pw_name) < OK ||
  217.         ml_txt (linebuf) < OK ||
  218.         ml_end (OK) < OK )
  219.     fprintf (stderr, "  *** notification error (%d)\n", errno);
  220. }
  221.  
  222. dirpart (path)
  223. char *path;
  224. {
  225.     register char *ptr;
  226.  
  227.     strcpy (dirname, path);
  228.     if (ptr = rindex(dirname+1, '/'))
  229.     *ptr = '\0';
  230.     else
  231.     dirname[0] = '\0';
  232. }
  233.  
  234. init_log()
  235. {
  236.     if( access(logfile, 02) == 0)
  237.     {
  238.     freopen (logfile, "a", stderr);
  239.     }
  240. }
  241.  
  242. fperror(s)
  243. char *s;
  244. {
  245.     fprintf(stderr, "%s: errno %d\n", s, errno);
  246. }
  247.